<template>
  <div v-if="hasError" class="error-boundary">
    <div class="error-content">
      <u-icon name="error-circle" size="64" color="#FF3B30"></u-icon>
      <h3 class="error-title">出現了一些問題</h3>
      <p class="error-message">{{ errorMessage }}</p>
      <div class="error-actions">
        <u-button 
          type="primary" 
          @click="handleRetry"
          :loading="isRetrying"
        >
          重試
        </u-button>
        <u-button 
          type="default" 
          @click="handleReset"
          class="ml-3"
        >
          重置
        </u-button>
      </div>
    </div>
  </div>
  <slot v-else></slot>
</template>

<script setup lang="ts">
import { ref, onErrorCaptured, provide } from 'vue'
import { logger } from '../utils/logger'

// Props
interface Props {
  fallback?: (error: Error, errorInfo: any) => any
}

const props = withDefaults(defineProps<Props>(), {
  fallback: undefined
})

// 響應式數據
const hasError = ref(false)
const error = ref<Error | null>(null)
const errorInfo = ref<any>(null)
const errorMessage = ref('')
const isRetrying = ref(false)

// 錯誤處理方法
const handleError = (err: Error, info: any) => {
  hasError.value = true
  error.value = err
  errorInfo.value = info
  errorMessage.value = err.message || '發生未知錯誤'
  
  // 記錄錯誤日誌
  logger.error('ErrorBoundary 捕獲到錯誤:', err, info)
  
  // 調用自定義 fallback
  if (props.fallback) {
    props.fallback(err, info)
  }
}

// 重試方法
const handleRetry = async () => {
  try {
    isRetrying.value = true
    hasError.value = false
    error.value = null
    errorInfo.value = null
    errorMessage.value = ''
    
    // 觸發重試事件
    emit('retry')
    
    logger.info('ErrorBoundary 重試成功')
  } catch (err) {
    logger.error('ErrorBoundary 重試失敗:', err)
    handleError(err as Error, null)
  } finally {
    isRetrying.value = false
  }
}

// 重置方法
const handleReset = () => {
  hasError.value = false
  error.value = null
  errorInfo.value = null
  errorMessage.value = ''
  
  // 觸發重置事件
  emit('reset')
  
  logger.info('ErrorBoundary 重置完成')
}

// 事件
const emit = defineEmits<{
  retry: []
  reset: []
}>()

// 捕獲錯誤
onErrorCaptured((err, instance, info) => {
  handleError(err, { instance, info })
  return false // 阻止錯誤繼續傳播
})

// 提供錯誤處理方法給子組件
provide('reportError', handleError)
</script>

<style scoped lang="scss">
.error-boundary {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400rpx;
  padding: 40rpx;
  background-color: var(--bg-secondary);
  border-radius: 16rpx;
  
  .error-content {
    text-align: center;
    
    .error-title {
      margin: 24rpx 0 16rpx;
      font-size: 32rpx;
      font-weight: 600;
      color: var(--text-primary);
    }
    
    .error-message {
      margin-bottom: 32rpx;
      font-size: 28rpx;
      color: var(--text-secondary);
      line-height: 1.5;
    }
    
    .error-actions {
      display: flex;
      justify-content: center;
      gap: 24rpx;
      
      .ml-3 {
        margin-left: 24rpx;
      }
    }
  }
}
</style>
